//
//  PthreadMutex.swift
//  sinaDemo
//
//  Created by admin on 2021/7/12.
//

import UIKit

class PthreadMutexLockDemo: LockBase {
    //互斥锁
    var  mutex:pthread_mutex_t = pthread_mutex_t.init()
    var  mutex1:pthread_mutex_t = pthread_mutex_t.init()
    //条件锁
    var  cond:pthread_cond_t = pthread_cond_t.init()
    var  mutex2:pthread_mutex_t = pthread_mutex_t.init()
    override init() {
        super.init()
        //初始化锁
        creatLock(Pointer: &mutex)
        creatLock(Pointer: &mutex1)
        creatLock(Pointer: &mutex2)
        
        //初始化条件
        var attr: pthread_condattr_t = pthread_condattr_t()
        pthread_condattr_init(&attr)
        pthread_cond_init(&cond, &attr)
    }
    private func creatLock(Pointer:UnsafeMutablePointer<pthread_mutex_t>) {
        var attr: pthread_mutexattr_t = pthread_mutexattr_t()
        pthread_mutexattr_init(&attr)
        //PTHREAD_MUTEX_RECURSIVE 代表递归锁。
        //何为递归锁，即当同一个线程中，方法1内加锁后再次调用方法1，那么递归锁可以正常进行。使用其他的锁则会产生死锁。一直在等待解锁。如果其他线程再次访问加锁内容，则会正常阻塞。
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)
        pthread_mutex_init(Pointer, &attr)
        //传入nil，默认为PTHREAD_MUTEX_DEFAULT模式
        //pthread_mutex_init(Pointer, nil)
    }
    deinit {
        //要释放一下
        pthread_mutex_destroy(&mutex)
        pthread_mutex_destroy(&mutex1)
    }
    override func saleTickets() {
        pthread_mutex_lock(&mutex)
        
        super.saleTickets()
        pthread_mutex_unlock(&mutex)
        
    }
    override func saveMoney() {
        pthread_mutex_lock(&mutex1)
        super.saveMoney()
        pthread_mutex_unlock(&mutex1)
        
    }
    override func payMoney() {
        pthread_mutex_lock(&mutex1)
        super.payMoney()
        pthread_mutex_unlock(&mutex1)
        
    }
    /*
     条件锁，举个例子🌰（同一个数组，一个add 另一个remove，remove得等数组不为空才remove，但是不同的异步线程进行增删操作。所以可以用到条件锁开进行控制）
     */
    //条件锁的测试
    private func condLockTest(){
        //加锁
        pthread_mutex_lock(&mutex2)
        print("condLockTest")
        //线程休眠，并且释放锁
        pthread_cond_wait(&cond, &mutex2)
        print("继续执行condLockTest")
        //解锁
        pthread_mutex_unlock(&mutex2)
    }
    private func condLockTest1(){
        //加锁
        pthread_mutex_lock(&mutex2)
        print("condLockTest1")
        //通知condLockTest其他线程，停止睡眠，将要继续执行，但是此时还未解锁，所以等到下面解锁后，会立即执行唤醒其他睡眠线程的操作
        pthread_cond_signal(&cond)
        //广播给所有的符合条件的线程
        //pthread_cond_broadcast(&cond)
        print("继续执行condLockTest1")
        //解锁
        pthread_mutex_unlock(&mutex2)
    }
}
